package com.qining618.cms.ucenter.controller.admin;

import com.qining618.cms.ucenter.controller.admin.request.AdminAuthLoginRequest;
import com.qining618.cms.ucenter.controller.admin.response.AdminAuthLoginResponse;
import com.qining618.cms.ucenter.domain.User;
import com.qining618.cms.ucenter.service.AdminService;
import com.qining618.cms.ucenter.service.RoleMenuService;
import com.qining618.cms.ucenter.service.TokenService;
import com.qining618.common.annotation.Access;
import com.qining618.common.context.ContextHandle;
import com.qining618.common.result.ApiResult;
import com.qining618.common.result.ErrorCode;
import com.qining618.common.utils.RequestUtil;
import com.qining618.common.utils.time.ClockUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author flt
 * @date 2019-09-20
 */
@RestController
@RequestMapping("/admin/api/ucenter/auth")
public class AdminAuthController {

    @Autowired
    private TokenService tokenService;
    @Autowired
    private AdminService adminService;
    @Autowired
    private RoleMenuService roleMenuService;

    @PostMapping("login")
    @Description("登录")
    public ApiResult login(
            HttpServletRequest request,
            @RequestBody @Validated AdminAuthLoginRequest authLoginRequest) {
        Date date = ClockUtil.currentDate();
        // 检验用户名
        User user = adminService.findByUsername(authLoginRequest.getUsername());
        if (user == null) {
            return ApiResult.failed(ErrorCode.PARAM_IS_INVALID, "用户名密码错误");
        }
        // 是否冻结
        if (user.getIsFreeze()) {
            // 冻结已到期、解冻
            if (user.getFreezeDueTime() != null && user.getFreezeDueTime().getTime() < date.getTime()) {
                adminService.unFreeze(user.getId());
            } else {
                return ApiResult.failed(ErrorCode.PARAM_IS_INVALID, "账户已被冻结");
            }
        }

        // 是否锁定
        boolean isLock = user.getIsLock() && (user.getLockDueTime() == null || user.getLockDueTime().getTime() > date.getTime());
        if (isLock) {
            return ApiResult.failed(ErrorCode.PARAM_IS_INVALID, "账户已被锁定");
        }

        // 密码检验
        String hashPassword = DigestUtils.md5Hex(authLoginRequest.getPassword());
        if (!Objects.equals(hashPassword, user.getPassword())) {
            // 更新密码错误记录
            adminService.updateLoginError(user.getId(), RequestUtil.getIpAddr(request));
            return ApiResult.failed(ErrorCode.PARAM_IS_INVALID, "用户名密码错误");
        }

        // 生成资源访问凭证
        String accessToken = tokenService.generateAccessToken(user.getId());

        List<String> codeList = new ArrayList<>();
        if (user.getRoleId() != null && user.getRoleId() != 0) {
            codeList = roleMenuService.getMenuCodeByRoleId(user.getRoleId());
        }

        // 登录返回信息
        AdminAuthLoginResponse authLoginResponse = AdminAuthLoginResponse.builder()
                .accessToken(accessToken)
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .avatar(user.getAvatar())
                .codes(codeList)
                .build();

        // 更新登录成功信息
        adminService.updateLoginSuccess(user.getId(), RequestUtil.getIpAddr(request));

        return ApiResult.ok(authLoginResponse);

    }

    @Access(needAdmin = true)
    @GetMapping("info")
    @Description("登录信息")
    public ApiResult getInfo() {
        Long userId = ContextHandle.getUserId();
        User user = adminService.findById(userId);

        List<String> codeList = new ArrayList<>();
        if (user.getRoleId() != null && user.getRoleId() != 0) {
            codeList = roleMenuService.getMenuCodeByRoleId(user.getRoleId());
        }

        AdminAuthLoginResponse authLoginResponse = AdminAuthLoginResponse.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .avatar(user.getAvatar())
                .codes(codeList)
                .build();
        return ApiResult.ok(authLoginResponse);
    }
}
